﻿#pragma execution_character_set("utf-8")

#include "WebSocketClient.h"
#include <QDebug>

#define syslog qDebug()

WSClient::WSClient(QObject *parent)
    : QObject(parent)
{
    WSClientObj = new QWebSocket(QString(), QWebSocketProtocol::VersionLatest, this);
//    WSClientObj->setParent(this);   //这里必须设置父对象，否则多线程运行时会报错
    //客户端需要处理的信号：连接成功、断开连接、发生错误、收到消息
    connect(WSClientObj, &QWebSocket::connected, this, &WSClient::on_connected);
    connect(WSClientObj, &QWebSocket::disconnected, this, &WSClient::on_disconnected);
    connect(WSClientObj, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(on_error(QAbstractSocket::SocketError)));
    connect(WSClientObj, &QWebSocket::textMessageReceived, this, &WSClient::NewTextMessage);    //信号连接
    connect(WSClientObj, &QWebSocket::binaryMessageReceived, this, &WSClient::NewBinaryMessage);    //信号连接

    pyProcess = new QProcess(this);

    timer = new QTimer(this);
    timer->setSingleShot(true);
    connect(timer, &QTimer::timeout, [this]{
        creat_url();
        if(timer->isSingleShot())
        {
            if(url.startsWith("wss"))
            {
               wss_config();
            }
            ConnectTo(url);
            timer->setSingleShot(false);
            timer->start(4*60*1000);    //每四分钟更新一次url，url有效期为300秒=5分钟
        }
    });
    timer->start(100);
}
 
void WSClient::creat_url()
{
    QString command = QCoreApplication::applicationDirPath() + "/create_url.py";
    QStringList cmdArgs;
    cmdArgs<<"/c"<<"python"<<command;
    pyProcess->start("cmd.exe", cmdArgs);
    pyProcess->waitForFinished();   //阻塞等待cmd执行完成
    url = QString::fromLocal8Bit(pyProcess->readAllStandardOutput());
    url.remove("\r\n");
}

WSClient::~WSClient()
{
    if(WSClientObj->state() == QAbstractSocket::ConnectedState)
    {
        WSClientObj->close();
    }
}

void WSClient::wss_config()
{
    QSslConfiguration conf = WSClientObj->sslConfiguration();
    conf.setPeerVerifyMode(QSslSocket::VerifyNone);
    conf.setProtocol(QSsl::TlsV1SslV3);
    WSClientObj->setSslConfiguration(conf);
}

QAbstractSocket::SocketState WSClient::connctionState()
{
    return WSClientObj->state();
}

//连接服务端
void WSClient::ConnectTo(const QString& url)
{

    WSClientObj->open(QUrl(url));
}

//断开连接
void WSClient::Disconnect()
{
    WSClientObj->close();
}
 //发消息，字符串
void WSClient::sendTextMessage(const QString& message)
{
    WSClientObj->sendTextMessage(message);
}

 //发消息，二进制
void WSClient::sendBinaryMessage(const QByteArray& data)
{
    WSClientObj->sendBinaryMessage(data);
}
 //连接成功，通知UI
void WSClient::on_connected()
{
    /*耗时操作......*/
    qDebug()<<"连接至ws服务器耗时"<<ElapsedTimer.elapsed()<<"毫秒";
    qDebug() << __FILE__ << __LINE__ << "websocket connected";
    emit connection_state("success connected", true);   //true/false用于UI判断更新控件可用状态
}
 //断开连接，通知UI
void WSClient::on_disconnected()
{
    qDebug() << __FILE__ << __LINE__ << "websocket disconnected";
    emit connection_state("success disconnected", false);

    ElapsedTimer.start();

    ConnectTo(url);

}
 //报错，通知UI
void WSClient::on_error(QAbstractSocket::SocketError error)
{
    if(error != QAbstractSocket::RemoteHostClosedError) //服务器主动断开连接
    {
        emit occur_error("error message:" + WSClientObj->errorString() + ",error code:" + QString::number(error));
    }
    qDebug() << __FILE__ << __LINE__ << (int)error << WSClientObj->errorString();
}
 //接收消息，通知UI
void WSClient::on_textMessageReceived(const QString& message)
{
    emit NewTextMessage(message);
}
void WSClient::on_binaryMessageReceived(const QByteArray& message)
{
    emit NewBinaryMessage(message);
}
